using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using HybridWebSocket;
using System;
using UnityEngine.UI; 
using System.Linq;
public class WebSocketDemo : MonoBehaviour
{
    [Header("当前房间玩家人数")]
    public int PlayerNum;
    [Header("服务器的地址")]
    public string IP;
    // UI
    public int gameState;
    public Image[] PlayerHealthUi;
    public GameObject ReadyButton;
    public GameObject RoomPanel;
    // 结算场景
    public GameObject FinishPanel;
    public Text FinishText;
    public Text CoinNum;

    // 话题
    [Header("所有玩家的生命值")]
    public float[] PlayerHealth;
    [Header("所有玩家的金币数")]
    public int[] Coin;
    [Header("所有玩家武器的生命值")]
    public float[][] PlayerSoldierHealth;
    // 接收的数据
    [Header("在线信息")]
    public bool[] isPlayerOnline;
    [Header("x、y坐标输入")]
    public float[] positionX;
    public float[] positionY;
    [Header("目标旋转角")]
    public float[] rotationZ;
    [Header("攻击状态")]
    public bool[] attackState;
    [Header("背包同步")]
    public int[][] Bag;
    // 发送的数据
    [Header("当前玩家的ID")]
    public int PlayerId;
    [Header("当前玩家的位移")]
    public float PlayerPositionX;
    public float PlayerPositionY;
    [Header("当前玩家的旋转")]
    public float PlayerRotationZ;
    [Header("当前玩家的开火")]
    public bool PlayerAttackState;
    [Header("当前玩家的背包")]
    public int[] playerBag;
    [Header("当前玩家的金币数量")]
    public int PlayerCoin;
    [Header("帧序号")]
    public int frameID;
    private WebSocket ws; // WebSocket 实例
    private int WinnerId;
    public int lastFrame;
    public float Speed;
    [Header("场地障碍物:x,y,r")]
    public Vector3[] obstacleList;

    // Use this for initialization
    void Start()
    {
        int RoomHost=GameObject.Find("端口").GetComponent<SaveParam>().Host;
        // 创建 WebSocket 实例
        ws = WebSocketFactory.CreateInstance(IP+RoomHost);

        // 添加 OnOpen 事件监听器
        ws.OnOpen += () =>
        {
            Debug.Log("WS connected!");
            Debug.Log("WS state: " + ws.GetState().ToString());
        };

        // 添加 OnMessage 事件监听器
        ws.OnMessage += (byte[] msg) =>
        {
            switch(gameState)
            {
                case 0:
                    break;
                case 1:
                    ReadyReceive(msg);
                    break;
                case 2:
                    InGameReceive(msg);
                    break;
                default:
                    break;
            }
        };

        // 添加 OnError 事件监听器
        ws.OnError += (string errMsg) =>
        {
            Debug.Log("WS error: " + errMsg);
        };

        // 添加 OnClose 事件监听器
        ws.OnClose += (WebSocketCloseCode code) =>
        {
            Debug.Log("WS closed with code: " + code.ToString());
            gameState=3;
        };

        // 连接到服务器
        ws.Connect();

        // 初始化
        positionX = new float[PlayerNum];
        positionY = new float[PlayerNum];
        rotationZ = new float[PlayerNum];
        attackState = new bool[PlayerNum];
        isPlayerOnline = new bool[PlayerNum];
        Coin = new int[PlayerNum];
        playerBag = new int[25];
        Bag = new int[PlayerNum][];
        for (int i = 0; i < Bag.Length; i++)
        {
            Bag[i] = new int[25];
        }
        PlayerSoldierHealth = new float[PlayerNum][];
        for (int i = 0; i < PlayerSoldierHealth.Length; i++)
        {
            PlayerSoldierHealth[i] = new float[25];
        }

        ReadyButton.GetComponent<Button>().onClick.AddListener(isReady);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        UiDisplay();
        PcInput();
        // 检查 WebSocket 是否已连接
        if (ws != null && ws.GetState() == WebSocketState.Open)
        {
            // 在这里实现你的循环逻辑
            // 例如，每秒发送一次消息
            switch(gameState)
            {
                case 0:
                    break;
                case 1:
                    ReadySendMessage();
                    if(PlayerId==-1)
                        break;
                    PlayerPositionX=GameObject.Find("Player"+PlayerId).transform.position.x;
                    PlayerPositionY=GameObject.Find("Player"+PlayerId).transform.position.y;
                    break;
                case 2:
                    RoomPanel.SetActive(false);
                    CoinNum.text="金币数："+Coin[PlayerId];
                    SendWebSocketMessage();
                    break;
                default:
                    OutGame();
                    break;
            }
            
        }
        else if(gameState==3)
        {
            FinishPanel.SetActive(true);
            FinishText.text="房间已满";
        }
    }

    void PcInput()
    {
        // 获取水平方向和垂直方向的输入
        float moveX = Input.GetAxis("Horizontal");
        float moveY = Input.GetAxis("Vertical");
        float nextPosX=PlayerPositionX+moveX*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        float nextPosY=PlayerPositionY+moveY*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        // 硬碰撞
        if(nextPosX>=25)
        {
            PlayerPositionX=PlayerPositionX;
            PlayerPositionY=PlayerPositionY+moveY*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        }
        else if(nextPosX<=-25)
        {
            PlayerPositionX=PlayerPositionX;
            PlayerPositionY=PlayerPositionY+moveY*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        }
        else if(nextPosY>=25)
        {
            PlayerPositionY=PlayerPositionY;
            PlayerPositionX=PlayerPositionX+moveX*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        }
        else if(nextPosY<-25)
        {
            PlayerPositionY=PlayerPositionY;
            PlayerPositionX=PlayerPositionX+moveX*(frameID-lastFrame)*Time.fixedDeltaTime*Speed;
        }
        else
        {
            PlayerPositionX=nextPosX;
            PlayerPositionY=nextPosY;
        }
        // if(nextPosX<25&&nextPosX>-25&&nextPosY>-25&&nextPosY<25)
        // {
        //     bool iscolider=false;
        //     for(int i=0;i<obstacleList.Length;i++)
        //     {
        //         Vector2 pointA = new Vector2(nextPosX, nextPosY);
        //         Vector2 pointB = new Vector2(obstacleList[i][0], obstacleList[i][1]);
        //         float distance = Vector2.Distance(pointA, pointB);
        //         if(distance<obstacleList[i][2])
        //         {
        //             iscolider=true;
        //             break;
        //         }
        //     }
        //     if(iscolider==false)
        //     {
        //         PlayerPositionX=nextPosX;
        //         PlayerPositionY=nextPosY;
        //     }
            
        // }
        
        lastFrame=frameID;

        // 获取鼠标位置
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.x=mousePosition.x-Screen.width/2;
        mousePosition.y=Screen.height/2-mousePosition.y;
        // 计算旋转角度
        PlayerRotationZ = Mathf.Atan2(mousePosition.y, mousePosition.x) * Mathf.Rad2Deg;
        PlayerAttackState = Input.GetMouseButton(0);

    }

    // 准备阶段
    void ReadyReceive(byte[] receiveMsg)
    {
        if(BitConverter.ToInt32(receiveMsg,0)==100)
        {
            gameState=2;
            return;
        }
        PlayerId=BitConverter.ToInt32(receiveMsg,0);
    }

    // 游戏进行阶段
    void InGameReceive(byte[] receiveMsg)
    {
        
        if(receiveMsg.Length<41&&frameID>20)
        {
            WinnerId=BitConverter.ToInt32(receiveMsg,0);
            if(WinnerId<PlayerNum)
            {
                gameState=3;
                return;
            }
            
        }
        int receivedLength=46+PlayerNum;
        for(int i=0;i<receiveMsg.Length/receivedLength;i++)
        {
            
            frameID=BitConverter.ToInt32(receiveMsg, i*receivedLength)+1;
            
            positionX[i]=BitConverter.ToSingle(receiveMsg, i*receivedLength+4);
            
            positionY[i]=BitConverter.ToSingle(receiveMsg,i*receivedLength+8);
            rotationZ[i]=BitConverter.ToSingle(receiveMsg,i*receivedLength+12);
            attackState[i]=BitConverter.ToBoolean(receiveMsg,i*receivedLength+16);
            for(int j=0;j<25;j++)
            {
                Bag[i][j]=(int)receiveMsg[j+i*receivedLength+17];
            }
            for(int j=0;j<PlayerNum;j++)
            {
                PlayerHealth[j]=Math.Min((int)receiveMsg[j+i*receivedLength+42],PlayerHealth[j]);
            }
            Coin[i]=BitConverter.ToInt32(receiveMsg,i*receivedLength+42+PlayerNum);
            
        }

    }

    void OutGame()
    {
        FinishPanel.SetActive(true);
        FinishText.text="玩家"+(WinnerId+1)+"获胜了";
        
    }
    // 准备阶段
    private void ReadySendMessage()
    {
        byte[] PlayerDataId = BitConverter.GetBytes(PlayerId);
        ws.Send(PlayerDataId);
    }
    // 发送 WebSocket 消息的方法
    private void SendWebSocketMessage()
    {
        byte[] PlayerDataId = BitConverter.GetBytes(PlayerId);
        byte[] frameDataId = BitConverter.GetBytes(frameID);
        byte[] positionDataX = BitConverter.GetBytes(PlayerPositionX);
        byte[] positionDataY = BitConverter.GetBytes(PlayerPositionY);
        byte[] rotationDataZ = BitConverter.GetBytes(PlayerRotationZ);
        byte[] bagData = new byte[25];
        for(int i=0;i<25;i++)
        {
            bagData[i]=(byte)playerBag[i];
        }

        byte[] playerHealthData = new byte[PlayerNum];
        for(int i=0;i<PlayerNum;i++)
        {
            playerHealthData[i]=(byte)PlayerHealth[i];
        }

        byte PlayerAttackDataState = (byte)(PlayerAttackState ? 1 : 0);
        byte[] PlayerDataCoin = BitConverter.GetBytes(PlayerCoin);
        
        int sendLength=frameDataId.Length+PlayerDataId.Length+ positionDataX.Length+ positionDataY.Length+ rotationDataZ.Length+1+25+PlayerNum+4;
        byte[] sendData = new byte[sendLength];

        Buffer.BlockCopy(PlayerDataId, 0, sendData, 0, 4);
        Buffer.BlockCopy(frameDataId, 0, sendData, 4, 4);
        Buffer.BlockCopy(positionDataX, 0, sendData, 8, 4);
        Buffer.BlockCopy(positionDataY, 0, sendData, 12, 4);
        Buffer.BlockCopy(rotationDataZ, 0, sendData, 16, 4);
        sendData[20]=PlayerAttackDataState;
        Buffer.BlockCopy(bagData, 0, sendData, 21, 25);
        Buffer.BlockCopy(playerHealthData, 0, sendData, 46,PlayerNum );
        Buffer.BlockCopy(PlayerDataCoin, 0, sendData, 46+PlayerNum,4);
        ws.Send(sendData);
    }

    // 当脚本被销毁时，确保关闭 WebSocket 连接
    void OnDestroy()
    {
        if (ws != null)
        {
            ws.Close();
        }
    }

    // ui显示
    void UiDisplay()
    {
        for(int i=0;i<PlayerNum;i++)
            PlayerHealthUi[i].fillAmount =PlayerHealth[i]/50f;
    }

    void isReady()
    {
        gameState=1;
        
        ReadyButton.SetActive(false);
    }

}
